

package com.hazelcast.map.impl.operation.steps.engine;

import javax.annotation.Nullable;

/**
 * Represents an isolated step of an operation. e.g.
 * {@link  com.hazelcast.map.impl.operation.PutOperation}
 * <p>
 * By using this interface, an operation can be modeled as
 * a collection of {@link Step}. With this model, offloadable steps
 * can be run in other threads than partitioned ones.
 *
 * @param <S> state object passed from one step to another
 */
public interface Step<S> {

    /**
     * Code to run at this step by using the provided state
     */
    void runStep(S state);

    /**
     * Idempotent next step finder.
     *
     * @param state state
     * @return next step or null if there is no next step.
     * @implSpec This implementation always throws
     * {@code UnsupportedOperationException}.
     */
    @Nullable
    default Step nextStep(S state) {
        throw new UnsupportedOperationException();
    }

    /**
     * @return {@code true} if this step must be
     * offloaded to a thread other than {@link
     * com.hazelcast.spi.impl.operationexecutor.impl.PartitionOperationThread}
     * otherwise {@code false}
     */
    default boolean isOffloadStep(S state) {
        return false;
    }

    /**
     * Used when this step is an
     * offload-step, otherwise not used.
     *
     * @param state the state object
     * @return name of the executor to run
     * this step(valid if this step is an offload-step)
     * @implSpec This implementation always throws
     * {@code UnsupportedOperationException}.
     */
    default String getExecutorName(S state) {
        throw new UnsupportedOperationException();
    }
}
